package core.algorithm.operator.Selection.triangle;

import core.algorithm.operator.Selection.AbstractSelection;
import core.algorithm.operator.Selection.SelectionCommonFunction;
import core.problem.Individual;
import core.problem.Population;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

/**
 *
 * @author 郝国生 HAO Guo-Sheng
 */
public class SinSelection extends AbstractSelection {

    @Override
    public List<Individual> getSelectionResult(Population population) {
        if (continueSelection(population)) {
            double fmax = population.getBestIndividual().getDecisionVariable().getFitness()[0],
                    fmin = population.getWorstIndividual().getDecisionVariable().getFitness()[0];
            double diff = fmax - fmin;
            double[] temFitness = new double[population.getIndividuals().size()];
            boolean need2Normalized = false;
            int i = 0;
            //用List的好处是：固定了个体的顺序，且便于获取
            List<Individual> individualList = new ArrayList<>(population.getIndividuals());
            for (Individual ind : individualList) {
                Objects.requireNonNull(ind);
                temFitness[i] = Math.sin(Math.PI / 2 * ((ind.getDecisionVariable().getFitness()[0] - fmin) / (diff)));
                assert temFitness[i] <= 1;
                assert temFitness[i] >= 0;
                i++;
            }
            if (need2Normalized) {
                double sum = 0;
                i = 0;
                for (; i < temFitness.length; i++) {
                    sum += temFitness[i];
                }
                i = 0;
                for (; i < temFitness.length; i++) {
                    temFitness[i] = temFitness[i] / sum;
                }
            }
            return new SelectionCommonFunction().getSelectionResult(individualList, temFitness);
        } else {
            return new LinkedList<>(population.getIndividuals());
        }
    }

}
